package com.example.hello;

import com.example.hello.client.ButtonGroup.BootstrapButtonGroupState;
import com.vaadin.shared.Connector;
import com.vaadin.ui.AbstractComponentContainer;
import com.vaadin.ui.Component;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

public class BootstrapButtonGroup extends AbstractComponentContainer {

    public enum ToggleType {
        CHECKBOX, NONE, RADIO
    }

    public BootstrapButtonGroup() {
        setToggle(ToggleType.NONE);
        setVertical(false);
    }

    public BootstrapButtonGroup(List<BootstrapButton> buttons) {
        this();
        setButtons(buttons);
    }

    public BootstrapButtonGroup(BootstrapButton... buttons) {
        this();
        for (BootstrapButton b : buttons) {
            addButton(b);
        }
    }

    public void BootstrapButtonGroup(Component button) {
        getState().addButton(button);
    }

    public List<Component> getButtons() {
        List<Component> buttons = new LinkedList<>();
        for (Connector connector : getState().getButtons()) {
            buttons.add((Component) connector);
        }

        return buttons;
    }

    public void setButtons(List<BootstrapButton> buttons) {
        List<Connector> connectorList = new LinkedList<>();
        for (BootstrapButton button : buttons) {
            connectorList.add(button);
        }

        getState().setButtons(connectorList);
    }

    @Override
    protected BootstrapButtonGroupState getState() {
        return (BootstrapButtonGroupState) super.getState();
    }

    public void addButton(BootstrapButton button) {
        addButton(button, getButtons().size());
    }

    private void addButton(BootstrapButton button, int index) {
        if (button.getParent() != null) {
            throw new IllegalArgumentException("Given button already has a parent component");
        }

        getState().addButton(button, index);
        super.addComponent(button);

        markAsDirty();
    }

    public void replaceButton(BootstrapButton oldButton, BootstrapButton newButton) {
        if (!getState().getButtons().contains(oldButton)) {
            throw new IllegalArgumentException("Given old button does not exist in this group");
        }

        int oldIndex = getState().getButtons().indexOf(oldButton);

        if (oldIndex == -1) {
            return;
        }

        removeButton(oldButton);
        addButton(newButton, oldIndex);
    }

    public boolean removeButton(BootstrapButton button) {
        if (!getState().getButtons().contains(button)) {
            return false;
        }

        getState().removeButton(button);
        super.removeComponent(button);

        markAsDirty();
        return true;
    }

    public void removeAllButtons() {
        getState().getButtons().clear();
        super.removeAllComponents();

        markAsDirty();
    }

    public ToggleType getToggle() {
        return ToggleType.valueOf(getState().getToggle());
    }

    public void setToggle(ToggleType toggleType) {
        getState().setToggle(toggleType.toString());
    }

    public boolean isVertical() {
        return getState().isVertical();
    }

    public void setVertical(boolean vertical) {
        getState().setVertical(vertical);
    }

    @Override
    public void addComponent(Component c) {
        throw new UnsupportedOperationException("Use addBootstrapButton method instead");
    }

    @Override
    public void removeComponent(Component c) {
        throw new UnsupportedOperationException("Use removeBootstrapButton method instead");
    }

    @Override
    public void removeAllComponents() {
        throw new UnsupportedOperationException("Use removeAllButtons instead");
    }

    @Override
    public Iterator<Component> iterator() {
        return getButtons().iterator();
    }

    @Override
    public void replaceComponent(Component oldComponent, Component newComponent) {
        throw new UnsupportedOperationException("Use replaceBootstrapButton method instead");
    }

    @Override
    public int getComponentCount() {
        return getState().getButtons().size();
    }

}